---
title: 身份认证
description: Astro 中的身份认证简介
i18nReady: true
---

import { Steps } from '@astrojs/starlight/components'
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'
import UIFrameworkTabs from '~/components/tabs/UIFrameworkTabs.astro'
import ReadMore from '~/components/ReadMore.astro'

认证和授权是两种安全过程，用来管理对你的网站或应用的访问。身份认证用于验证访客的身份，而授权则允许访问受保护的区域和资源。

认证允许你为登录的个人定制你的网站的特定区域，并为个人或私人信息提供最大程度的保护。认证库（例如 [Better Auth](https://better-auth.com/)、[Clerk](https://clerk.com)）为多种认证方法提供了实用工具，如电子邮件登录和 OAuth 提供商。

:::tip
Astro 没有官方的认证解决方案，但你可以在集成目录中找到 [社区的“auth”集成](https://astro.build/integrations/?search=auth)。
:::

<ReadMore>查看我们的专门指南，了解如何 [使用 Supabase 添加认证](/zh-cn/guides/backend/supabase/#使用-supabase-添加身份验证) 或 [使用 Firebase 添加认证](/zh-cn/guides/backend/firebase/#使用-firebase-添加身份验证)，以获取这些后端服务的详细信息。</ReadMore>

## Better Auth

Better Auth 是一个与框架无关的 TypeScript 身份验证（和授权）框架。它提供了一套全面的开箱即用功能，并包含一个插件生态系统，可简化添加高级功能的过程。

它开箱即用地支持 Astro，你可以使用它为你的 astro 项目添加身份验证。

### 安装

<PackageManagerTabs>
  <Fragment slot="npm">
  ```shell
  npm install better-auth
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```shell
  pnpm add better-auth
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```shell
  yarn add better-auth
  ```
  </Fragment>
</PackageManagerTabs>

有关详细的设置说明，请查看 [Better Auth 安装指南](https://www.better-auth.com/docs/installation)。

### 配置

依照 [Better Auth 安装指南](https://www.better-auth.com/docs/installation#configure-database) 中所述，配置数据库表以存储用户数据和你的首选身份验证方法。然后，你需要在 Astro 项目中挂载 Better Auth 处理程序。

```ts title="src/pages/api/auth/[...all].ts"
import { auth } from "../../../lib/auth"; // 导入你的 Better Auth 实例
import type { APIRoute } from "astro";

export const prerender = false; // 'server' 模式下，无需配置

export const ALL: APIRoute = async (ctx) => {
	return auth.handler(ctx.request);
};
```

请参照 [Better Auth Astro 指南](https://www.better-auth.com/docs/integrations/astro) 以了解更多信息。

### 使用方法

Better Auth 为各种框架提供了 `createAuthClient` 助手，包括 Vanilla JS、React、Vue、Svelte 和 Solid。

例如，要为 React 创建客户端，请从 `better-auth/react` 导入助手：



<UIFrameworkTabs>
  <Fragment slot="react">
   ```ts title="src/lib/auth-client.ts"
  import { createAuthClient } from 'better-auth/react';

  export const authClient = createAuthClient();

  export const { signIn, signOut } = authClient;
  ```
  </Fragment>
  <Fragment slot="solid">
  ```ts title="src/lib/auth-client.ts"
  import { createAuthClient } from 'better-auth/solid';

  export const authClient = createAuthClient();

  export const { signIn, signOut } = authClient;
  ```
  </Fragment>
  <Fragment slot="svelte">
   ```ts title="src/lib/auth-client.ts"
  import { createAuthClient } from 'better-auth/svelte';

  export const authClient = createAuthClient();

  export const { signIn, signOut } = authClient;
  ```
  </Fragment>
  <Fragment slot="vue">
  ```ts title="src/lib/auth-client.ts"
  import { createAuthClient } from 'better-auth/vue';

  export const authClient = createAuthClient();

  export const { signIn, signOut } = authClient;
  ```
  </Fragment>
</UIFrameworkTabs>

设置客户端后，你可以使用它来验证 Astro 组件或任何位于特定框架下的文件中的用户。以下示例添加了使用配置的 `signIn()` 和 `signOut()` 函数以验证登录或注销的功能。

```astro title="src/pages/index.astro"
---
import Layout from 'src/layouts/Base.astro';
---
<Layout>
  <button id="login">登录</button>
  <button id="logout">注销</button>

  <script>
    const { signIn, signOut } = await import("./lib/auth-client")
    document.querySelector("#login").onclick = () => signIn.social({
      provider: "github",
      callbackURL: "/dashboard",
    })
    document.querySelector("#logout").onclick = () => signOut()
  </script>
</Layout>
```

然后，你可以使用 `auth` 对象以在服务器端代码中获取用户的会话数据。以下示例展示了一种个性化页面内容的方式，它通过显示经过了身份验证的用户名来实现：

```astro title="src/pages/index.astro"
---
import { auth } from "../../../lib/auth"; // 导入你的 Better Auth 实例

export const prerender = false; // 'server' 模式下，无需配置

const session = await auth.api.getSession({
	headers: Astro.request.headers,
});
---

<p>{session.user?.name}</p>
```

你还可以使用 `auth` 对象来通过中间件以保护你的路由。以下示例检查了尝试访问登录仪表板路由的用户是否已通过身份验证，如果未通过身份验证，则将其重定向到主页。

```ts title="src/middleware.ts"
import { auth } from "../../../auth"; // 导入你的 Better Auth 实例
import { defineMiddleware } from "astro:middleware";

export const onRequest = defineMiddleware(async (context, next) => {
	const isAuthed = await auth.api
		.getSession({
			headers: context.request.headers,
		})
	if (context.url.pathname === "/dashboard" && !isAuthed) {
		return context.redirect("/");
	}
	return next();
});
```

### 下一步

- [Better Auth Astro 指南](https://www.better-auth.com/docs/integrations/astro)
- [Better Auth Astro 示例](https://github.com/better-auth/examples/tree/main/astro-example)
- [Better Auth 文档](https://www.better-auth.com/docs)
- [Better Auth 的 GitHub 仓库](https://github.com/better-auth/better-auth)


## Clerk

Clerk 是一套完整的系统，它拥有嵌入式 UI、灵活的 API 以及用于验证和管理用户的仪表盘。[Clerk 的官方 Astro SDK](https://clerk.com/docs/references/astro/overview) 现已推出。

### 安装

使用你选择的包管理器安装 `@clerk/astro`。

<PackageManagerTabs>
  <Fragment slot="npm">
  ```shell
  npm install @clerk/astro
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```shell
  pnpm add @clerk/astro
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```shell
  yarn add @clerk/astro
  ```
  </Fragment>
</PackageManagerTabs>

### 配置

按照 [Clerk 自己的 Astro 快速入门指南](https://clerk.com/docs/quickstarts/astro) 在你的 Astro 项目中设置 Clerk 集成和中间件。

### 使用方法

Clerk 提供的组件允许你根据用户的身份验证状态控制页面的可见性。向已注销的用户显示登录按钮，而不是向已登录的用户显示可用的内容：

```astro title="src/pages/index.astro"
---
import Layout from 'src/layouts/Base.astro';
import { SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/astro/components';

export const prerender = false; // 'server' 模式下，无需配置
---

<Layout>
    <SignedIn>
        <UserButton />
    </SignedIn>
    <SignedOut>
        <SignInButton />
    </SignedOut>
</Layout>
```

Clerk 还允许你使用中间件以保护服务器上的路由。指定受保护的路由，并提示未经身份验证的用户登录：

```ts title="src/middleware.ts"
import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server';

const isProtectedRoute = createRouteMatcher([
  '/dashboard(.*)',
  '/forum(.*)',
]);

export const onRequest = clerkMiddleware((auth, context) => {
  if (!auth().userId && isProtectedRoute(context.request)) {
    return auth().redirectToSignIn();
  }
});
```

### 下一步

- 阅读 [官方 `@clerk/astro` 文档](https://clerk.com/docs/references/astro/overview)
- 从 [Clerk + Astro 快速入门项目](https://github.com/clerk/clerk-astro-quickstart) 的模板开始

## Lucia

[Lucia](https://lucia-auth.com/) 是一个用于在许多框架（包括 Astro）中实现基于会话的身份验证的资源。

### 指南

<Steps>

1. 使用你选择的数据库创建一个 [基本会话 API](https://lucia-auth.com/sessions/basic-api/)。
2. 使用端点和中间件添加 [会话 cookie](https://lucia-auth.com/sessions/cookies/astro)。
3. 使用你创建的 API 实现 [GitHub OAuth](https://lucia-auth.com/tutorials/github-oauth/astro)。

</Steps>

### 示例

- [Astro 中的 GitHub OAuth 示例](https://github.com/lucia-auth/example-astro-github-oauth)
- [Astro 中的 Google OAuth 示例](https://github.com/lucia-auth/example-astro-google-oauth)
- [在 Astro 中使用 2FA 的电子邮件和密码的示例](https://github.com/lucia-auth/example-astro-email-password-2fa)
- [在 Astro 中使用 2FA 和 WebAuthn 的电子邮件和密码的示例](https://github.com/lucia-auth/example-astro-email-password-webauthn)

## 社区资源

- [在 Astro 和 Azure 静态 Web 应用中使用 Microsoft Entra Id EasyAuth](https://agramont.net/blog/entra-id-easyauth-with-astro/)
